



<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#FFF">
  <link rel="apple-touch-icon" sizes="180x180" href="/blog/images/apple-touch-icon.png">

<link rel="icon" type="image/ico" sizes="32x32" href="/blog/images/favicon.ico">
  <meta http-equiv="Cache-Control" content="no-transform">
  <meta http-equiv="Cache-Control" content="no-siteapp">


<link rel="alternate" type="application/rss+xml" title="宋胖子" href="https://song-ruipeng.gitee.io/blog/rss.xml" />
<link rel="alternate" type="application/atom+xml" title="宋胖子" href="https://song-ruipeng.gitee.io/blog/atom.xml" />
<link rel="alternate" type="application/json" title="宋胖子" href="https://song-ruipeng.gitee.io/blog/feed.json" />

<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Mulish:300,300italic,400,400italic,700,700italic%7CFredericka%20the%20Great:300,300italic,400,400italic,700,700italic%7CNoto%20Serif%20JP:300,300italic,400,400italic,700,700italic%7CNoto%20Serif%20SC:300,300italic,400,400italic,700,700italic%7CInconsolata:300,300italic,400,400italic,700,700italic&display=swap&subset=latin,latin-ext">

<link rel="stylesheet" href="/blog/css/app.css?v=0.2.5">

  
  <meta name="keywords" content="少时诵诗书" />


<link rel="canonical" href="https://song-ruipeng.gitee.io/blog/2023/05/17/%E5%9B%9B.JS/">



  <title>
JS - 我的日志 |
Yume Shoka = 宋胖子</title>
<meta name="generator" content="Hexo 6.3.0"></head>
<body itemscope itemtype="http://schema.org/WebPage">
  <div id="loading">
    <div class="cat">
      <div class="body"></div>
      <div class="head">
        <div class="face"></div>
      </div>
      <div class="foot">
        <div class="tummy-end"></div>
        <div class="bottom"></div>
        <div class="legs left"></div>
        <div class="legs right"></div>
      </div>
      <div class="paw">
        <div class="hands left"></div>
        <div class="hands right"></div>
      </div>
    </div>
  </div>
  <div id="container">
    <header id="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="inner">
        <div id="brand">
          <div class="pjax">
          
  <h1 itemprop="name headline">JS
  </h1>
  
<div class="meta">
  <span class="item" title="创建时间：2023-05-17 16:24:00">
    <span class="icon">
      <i class="ic i-calendar"></i>
    </span>
    <span class="text">发表于</span>
    <time itemprop="dateCreated datePublished" datetime="2023-05-17T16:24:00+08:00">2023-05-17</time>
  </span>
</div>


          </div>
        </div>
        <nav id="nav">
  <div class="inner">
    <div class="toggle">
      <div class="lines" aria-label="切换导航栏">
        <span class="line"></span>
        <span class="line"></span>
        <span class="line"></span>
      </div>
    </div>
    <ul class="menu">
      <li class="item title"><a href="/blog/" rel="start">Yume Shoka</a></li>
    </ul>
    <ul class="right">
      <li class="item theme">
        <i class="ic i-sun"></i>
      </li>
      <li class="item search">
        <i class="ic i-search"></i>
      </li>
    </ul>
  </div>
</nav>

      </div>
      <div id="imgs" class="pjax">
        <ul>
          <li class="item" data-background-image=" https://cancan-wx.oss-cn-hangzhou.aliyuncs.com/bg/6833939bly1gipevuctzzj20zk0m84qp.jpg"></li>
          <li class="item" data-background-image=" https://cancan-wx.oss-cn-hangzhou.aliyuncs.com/bg/6833939bly1gipetfk5zwj20zk0m8e81.jpg"></li>
          <li class="item" data-background-image=" https://cancan-wx.oss-cn-hangzhou.aliyuncs.com/bg/6833939bly1gicis081o9j20zk0m8dmr.jpg"></li>
          <li class="item" data-background-image=" https://cancan-wx.oss-cn-hangzhou.aliyuncs.com/bg/6833939bly1giclimtf7dj20zk0m8qav.jpg"></li>
          <li class="item" data-background-image=" https://cancan-wx.oss-cn-hangzhou.aliyuncs.com/bg/6833939bly1gicit4jrvuj20zk0m8785.jpg"></li>
          <li class="item" data-background-image=" https://cancan-wx.oss-cn-hangzhou.aliyuncs.com/bg/6833939bly1giciryrr3rj20zk0m8nhk.jpg"></li>
        </ul>
      </div>
    </header>
    <div id="waves">
      <svg class="waves" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 24 150 28" preserveAspectRatio="none" shape-rendering="auto">
        <defs>
          <path id="gentle-wave" d="M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z" />
        </defs>
        <g class="parallax">
          <use xlink:href="#gentle-wave" x="48" y="0" />
          <use xlink:href="#gentle-wave" x="48" y="3" />
          <use xlink:href="#gentle-wave" x="48" y="5" />
          <use xlink:href="#gentle-wave" x="48" y="7" />
        </g>
      </svg>
    </div>
    <main>
      <div class="inner">
        <div id="main" class="pjax">
          
  <div class="article wrap">
    
<div class="breadcrumb" itemscope itemtype="https://schema.org/BreadcrumbList">
<i class="ic i-home"></i>
<span><a href="/blog/">首页</a></span><i class="ic i-angle-right"></i>
<span  class="current" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"><a href="/blog/categories/%E6%88%91%E7%9A%84%E6%97%A5%E5%BF%97/" itemprop="item" rel="index" title="分类于 我的日志"><span itemprop="name">我的日志</span></a>
<meta itemprop="position" content="1" /></span>
</div>

    <article itemscope itemtype="http://schema.org/Article" class="post block" lang="zh-CN">
  <link itemprop="mainEntityOfPage" href="https://song-ruipeng.gitee.io/blog/2023/05/17/%E5%9B%9B.JS/">

  <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
    <meta itemprop="image" content="/blog/images/avatar.jpg">
    <meta itemprop="name" content="宋胖子">
    <meta itemprop="description" content=", 欢迎大家一起交流">
  </span>

  <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
    <meta itemprop="name" content="宋胖子">
  </span>

  <div class="body md" itemprop="articleBody">
    

    <h3 id="四js"><a class="markdownIt-Anchor" href="#四js">#</a> 四.JS</h3>
<h3 id="41-js数据类型有哪些他们的区别是什么"><a class="markdownIt-Anchor" href="#41-js数据类型有哪些他们的区别是什么">#</a> 4.1 <strong>JS 数据类型有哪些，他们的区别是什么？</strong></h3>
<h6 id="答"><a class="markdownIt-Anchor" href="#答">#</a> 答:</h6>
<pre><code>JS共八种类型:Undifined,Null,Boolean,Number,String,Object,Biglnt,Symbol
</code></pre>
<p>其中 Biglnt 和 Symbol 是 es6 新增的数据类型</p>
<ul>
<li>Symbol 代表创建后<strong>独一无二且不可变</strong>的数据类型，它主要是为了解决可能出现的<strong>全局变量冲突</strong>的问题。</li>
<li>BigInt 是一种<strong>数字类型</strong>的数据，它可以表示任意精度格式的整数，使用 BigInt 可以<strong>安全地存储和操作大整数</strong>，即使这个数已经超出了 Number 能够表示的<strong>安全整数范围</strong>。<br>
这些数据可以分为原始数据类型和引用数据类型:</li>
<li>栈：原始数据类型（Undifined,Null,Boolean,Number,string）</li>
<li>堆：引用数据类型（对象，数组和函数）</li>
</ul>
<p>两种类型的区别在于<strong>存储位置的不同</strong>:</p>
<ul>
<li>原始数据类型直接存储在栈（stack）中的简单数据段，占据空间小，大小固定，属于被频繁使用数据，所以放在栈中存储:</li>
<li>引用数据类型存储在堆（heap）中的对象，占据空间大，大小不固定，如果存储在栈中，将会影响程序运行的性能；</li>
</ul>
<p>堆和栈的概念存在于数据结构和操作系统内存中，在数据结构中:</p>
<ul>
<li>数据结构中，栈的数据的存取方式是先进后出。</li>
<li>堆是一个优先队列，是按优先级来进行排序的，优先级可以按照大小来规定（先进先出）。</li>
</ul>
<p>在操作系统中。内存被分为栈区和堆区:</p>
<ul>
<li>栈区内存由编译器自动分配释放，存放函数的参数值，局部变量的值等。其操作方式类似于数据结构中的栈。</li>
<li>堆区内存一般由开发者分配释放，若开发者不释放，程序结束时可能有垃圾回收机制回收。</li>
</ul>
<h3 id="2-数据类型检测的方式有哪些"><a class="markdownIt-Anchor" href="#2-数据类型检测的方式有哪些">#</a> 2. 数据类型检测的方式有哪些</h3>
<p><strong>（1）typeof</strong></p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="keyword">typeof</span> <span class="number">2</span>);               <span class="comment">// number</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="keyword">typeof</span> <span class="literal">true</span>);            <span class="comment">// boolean</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="keyword">typeof</span> <span class="string">&#x27;str&#x27;</span>);           <span class="comment">// string</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="keyword">typeof</span> []);              <span class="comment">// object    </span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="keyword">typeof</span> <span class="keyword">function</span>(<span class="params"></span>)&#123;&#125;);    <span class="comment">// function</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="keyword">typeof</span> &#123;&#125;);              <span class="comment">// object</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="keyword">typeof</span> <span class="literal">undefined</span>);       <span class="comment">// undefined</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="keyword">typeof</span> <span class="literal">null</span>);            <span class="comment">// object</span></span><br></pre></td></tr></table></figure>
<p>其中数组、对象、null 都会被判断为 object，其他判断都正确。<br>
<strong>注</strong>：其实数组也是对象，根据原型链的概念原型链的终点就是 null。故数组，对象，null 都会判断为 object！</p>
<p><strong>（2）instance of 则填补了无法判断 object 内部类型的问题</strong></p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="number">2</span> <span class="keyword">instanceof</span> <span class="title class_">Number</span>)   <span class="comment">//false</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="literal">true</span> <span class="keyword">instanceof</span> <span class="title class_">Boolean</span>)   <span class="comment">//false</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;str&#x27;</span> <span class="keyword">instanceof</span> <span class="title class_">String</span>)   <span class="comment">//false</span></span><br><span class="line"></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>([] <span class="keyword">instanceof</span> <span class="title class_">Array</span>)  <span class="comment">//true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="keyword">function</span> <span class="keyword">of</span> &#123;&#125; <span class="keyword">instanceof</span> <span class="title class_">Function</span>) <span class="comment">//true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(&#123;&#125; <span class="keyword">instanceof</span> <span class="title class_">Object</span>) <span class="comment">//true</span></span><br></pre></td></tr></table></figure>
<p>可以看出，instanceof<strong> 只能正确判断引用数据类型</strong>，而不能判断基本数据类型。instanceof 运算符可以用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。</p>
<p><strong>（3） constructor</strong></p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>((<span class="number">2</span>).<span class="property">constructor</span> === <span class="title class_">Number</span>); <span class="comment">// true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>((<span class="literal">true</span>).<span class="property">constructor</span> === <span class="title class_">Boolean</span>); <span class="comment">// true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>((<span class="string">&#x27;str&#x27;</span>).<span class="property">constructor</span> === <span class="title class_">String</span>); <span class="comment">// true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(([]).<span class="property">constructor</span> === <span class="title class_">Array</span>); <span class="comment">// true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>((<span class="keyword">function</span>(<span class="params"></span>) &#123;&#125;).<span class="property">constructor</span> === <span class="title class_">Function</span>); <span class="comment">// true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>((&#123;&#125;).<span class="property">constructor</span> === <span class="title class_">Object</span>); <span class="comment">// true</span></span><br></pre></td></tr></table></figure>
<p><code>constructor</code>  有两个作用，一是判断数据的类型，二是对象实例通过  <code>constrcutor</code>  对象访问它的构造函数。需要注意，如果创建一个对象来改变它的原型， <code>constructor</code>  就不能用来判断数据类型了：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">Fn</span>(<span class="params"></span>)&#123;&#125;;</span><br><span class="line"> </span><br><span class="line"><span class="title class_">Fn</span>.<span class="property"><span class="keyword">prototype</span></span> = <span class="keyword">new</span> <span class="title class_">Array</span>();</span><br><span class="line"> </span><br><span class="line"><span class="keyword">var</span> f = <span class="keyword">new</span> <span class="title class_">Fn</span>();</span><br><span class="line"> </span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(f.<span class="property">constructor</span>===<span class="title class_">Fn</span>);    <span class="comment">// false</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(f.<span class="property">constructor</span>===<span class="title class_">Array</span>); <span class="comment">// true</span></span><br></pre></td></tr></table></figure>
<p><strong>(4) Object.prototype.toString.call()</strong></p>
<p>Object.prototype.toString.call () 使用 Object 对象的原型方法 toString 来判断数据类型:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> a = <span class="title class_">Object</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">toString</span>;</span><br><span class="line"> </span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a.<span class="title function_">call</span>(<span class="number">2</span>));</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a.<span class="title function_">call</span>(<span class="literal">true</span>));</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a.<span class="title function_">call</span>(<span class="string">&#x27;str&#x27;</span>));</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a.<span class="title function_">call</span>([]));</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a.<span class="title function_">call</span>(<span class="keyword">function</span>(<span class="params"></span>)&#123;&#125;));</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a.<span class="title function_">call</span>(&#123;&#125;));</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a.<span class="title function_">call</span>(<span class="literal">undefined</span>));</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a.<span class="title function_">call</span>(<span class="literal">null</span>));</span><br></pre></td></tr></table></figure>
<p>同样是检测对象 obj 调用 toString 方法，obj.toString () 的结果和 Object.prototype.toString.call (obj) 的结果不一样，这是为什么？</p>
<pre><code>这是因为toString是Object的原型方法，而Array,function等类型作为Object的实例，都重写toString方法,不通过的对象类型调用toString方法时，根据原型链的知识，调用的是对应的重写之后的toString方法(function类型返回内容为函数体的字符串，Array类型返回元素组成的字符串..)，而不会调用Object上原型toString方法（返回对象的具体类型）,所以采用obj.toString()不能得到其对象类型，只能将obj转换为字符串类型；因此，在想要得到对象的具体类型时，应该调用Object原型上的toString方法。
</code></pre>
<h3 id="3-判断数组的方式有哪些"><a class="markdownIt-Anchor" href="#3-判断数组的方式有哪些">#</a> 3. 判断数组的方式有哪些？</h3>
<ul>
<li>通过 Object.prototype.toString.call () 判断</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="title class_">Object</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">toString</span>.<span class="title function_">call</span>(obj).<span class="property">slice</span>*(<span class="number">8</span>,-<span class="number">1</span>)===<span class="string">&#x27;Array&#x27;</span></span><br></pre></td></tr></table></figure>
<ul>
<li>通过原型链做判断</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">obj.<span class="property">_proto_</span>===<span class="title class_">Array</span>.<span class="property"><span class="keyword">prototype</span></span></span><br></pre></td></tr></table></figure>
<ul>
<li>通过 ES6 的 Array.isArray () 做判断</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="title class_">Array</span>.<span class="title function_">isArray</span>(obj)</span><br></pre></td></tr></table></figure>
<ul>
<li>通过 instanceof 做判断</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">obj <span class="keyword">instanceof</span> <span class="title class_">Array</span></span><br></pre></td></tr></table></figure>
<ul>
<li>通过 Array.prototype.isPrototypeof</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="title class_">Array</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="title function_">isPrototypeof</span>(obj)</span><br></pre></td></tr></table></figure>
<p>注：isPrototypeOf () 方法用于检查一个对象是否存在于另一个对象的原型链</p>
<h3 id="4-undefined和null"><a class="markdownIt-Anchor" href="#4-undefined和null">#</a> 4. Undefined 和 Null</h3>
<p><strong>（1）相同点</strong><br>
首先 undefined 和 null 都是基本数据类型，这两个基本数据类型分别都只有一个值，就是 undefined 和 null<br>
<strong>（2）基本含义</strong><br>
 undefined 代表的含义是<strong>未定义</strong>，null 代表的含义是<strong>空对象</strong>，一般变量声明了但还没有定义的时候会返回 undefined,null 主要用于赋值给一些可能会返回对象的变量，作为初始化。<br>
<strong>（3）typeof 判断</strong><br>
当对这两种类型使用 typeof 进行判断时，Null 类型会返回’Object’,== true,===false</p>
<h3 id="7-为什么0102-03如何让其相等"><a class="markdownIt-Anchor" href="#7-为什么0102-03如何让其相等">#</a> 7. 为什么 0.1+0.2 ! == 0.3，如何让其相等</h3>
<p>在开发过程中遇到类似这样的问题：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">let n1 = 0.1, n2 = 0.2</span><br><span class="line">console.log(n1 + n2)  // 0.30000000000000004</span><br></pre></td></tr></table></figure>
<p>这里得到的不是想要的结果，要想等于 0.3，就要把它进行转化：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">(n1 + n2).toFixed(2) // 注意，toFixed为四舍五入</span><br></pre></td></tr></table></figure>
<p><code>toFixed(num)</code>  方法可把 Number 四舍五入为指定小数位数的数字。那为什么会出现这样的结果呢？</p>
<p>计算机是通过二进制的方式存储数据的，所以计算机计算 0.1+0.2 的时候，实际上是计算的两个数的二进制的和。0.1 的二进制是 <code>0.0001100110011001100...</code> （1100 循环），0.2 的二进制是： <code>0.00110011001100...</code> （1100 循环），这两个数的二进制都是无限循环的数。那 JavaScript 是如何处理无限循环的二进制小数呢？</p>
<p>一般我们认为数字包括整数和小数，但是在 JavaScript 中只有一种数字类型：Number，它的实现遵循 IEEE 754 标准，使用 64 位固定长度来表示，也就是标准的 double 双精度浮点数。在二进制科学表示法中，双精度浮点数的小数部分最多只能保留 52 位，再加上前面的 1，其实就是保留 53 位有效数字，剩余的需要舍去，遵从 “0 舍 1 入” 的原则。</p>
<p>根据这个原则，0.1 和 0.2 的二进制数相加，再转化为十进制数就是： <code>0.30000000000000004</code> 。</p>
<p>下面看一下<strong>双精度数是如何保存</strong>的：</p>
<p><img data-src="https://cancan-wx.oss-cn-hangzhou.aliyuncs.com/bg/2020080420355853.png" alt="image"></p>
<ul>
<li>第一部分（蓝色）：用来存储符号位（sign），用来区分正负数，0 表示正数，占用 1 位</li>
<li>第二部分（绿色）：用来存储指数（exponent），占用 11 位</li>
<li>第三部分（红色）：用来存储小数（fraction），占用 52 位</li>
</ul>
<p>对于 0.1，它的二进制为：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">0.00011001100110011001100110011001100110011001100110011001 10011...</span><br></pre></td></tr></table></figure>
<p>转为科学计数法（科学计数法的结果就是浮点数）：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">1.1001100110011001100110011001100110011001100110011001*2^-4</span><br></pre></td></tr></table></figure>
<p>可以看出 0.1 的符号位为 0，指数位为 - 4，小数位为：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">1001100110011001100110011001100110011001100110011001</span><br></pre></td></tr></table></figure>
<p>那么问题又来了，<strong>指数位是负数，该如何保存</strong>呢？</p>
<p>IEEE 标准规定了一个偏移量，对于指数部分，每次都加这个偏移量进行保存，这样即使指数是负数，那么加上这个偏移量也就是正数了。由于 JavaScript 的数字是双精度数，这里就以双精度数为例，它的指数部分为 11 位，能表示的范围就是 0~2047，IEEE 固定<strong>双精度数的偏移量为 1023</strong>。</p>
<ul>
<li>当指数位不全是 0 也不全是 1 时 (规格化的数值)，IEEE 规定，阶码计算公式为 e-Bias。 此时 e 最小值是 1，则 1-1023= -1022，e 最大值是 2046，则 2046-1023=1023，可以看到，这种情况下取值范围是 <code>-1022~1013</code> 。</li>
<li>当指数位全部是 0 的时候 (非规格化的数值)，IEEE 规定，阶码的计算公式为 1-Bias，即 1-1023= -1022。</li>
<li>当指数位全部是 1 的时候 (特殊值)，IEEE 规定这个浮点数可用来表示 3 个特殊值，分别是正无穷，负无穷，NaN。 具体的，小数位不为 0 的时候表示 NaN；小数位为 0 时，当符号位 s=0 时表示正无穷，s=1 时候表示负无穷。</li>
</ul>
<p>对于上面的 0.1 的指数位为 - 4，-4+1023 = 1019 转化为二进制就是： <code>1111111011</code> .</p>
<p>所以，0.1 表示为：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">0 1111111011 1001100110011001100110011001100110011001100110011001</span><br></pre></td></tr></table></figure>
<p>说了这么多，是时候该最开始的问题了，如何实现 0.1+0.2=0.3 呢？</p>
<p>对于这个问题，一个直接的解决方法就是设置一个误差范围，通常称为 “机器精度”。对 JavaScript 来说，这个值通常为 2-52，在 ES6 中，提供了 <code>Number.EPSILON</code>  属性，而它的值就是 2-52，只要判断 <code>0.1+0.2-0.3</code>  是否小于 <code>Number.EPSILON</code> ，如果小于，就可以判断为 0.1+0.2 ===0.3</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">function numberepsilon(arg1,arg2)&#123;                   </span><br><span class="line">  return Math.abs(arg1 - arg2) &lt; Number.EPSILON;        </span><br><span class="line">&#125;        </span><br><span class="line"></span><br><span class="line">console.log(numberepsilon(0.1 + 0.2, 0.3)); // true</span><br></pre></td></tr></table></figure>
<h2 id="二-es6"><a class="markdownIt-Anchor" href="#二-es6">#</a> 二、ES6</h2>
<h3 id="1-let-const-var的区别"><a class="markdownIt-Anchor" href="#1-let-const-var的区别">#</a> 1. let、const、var 的区别</h3>
<p><strong>（1）块级作用域：</strong> 块作用域由  <code>&#123; &#125;</code>  包括，let 和 const 具有块级作用域，var 不存在块级作用域。块级作用域解决了 ES5 中的两个问题：</p>
<ul>
<li>内层变量可能覆盖外层变量</li>
<li>用来计数的循环变量泄露为全局变量</li>
</ul>
<p><strong>（2）变量提升：</strong> var 存在变量提示，let 和 const 不存在变量提升，即在变量只能在声明之后使用，否则会报错。<br>
<strong>（3）给全局添加属性：</strong> 浏览器的全局对象是 window，Node 的全局对象是 global。var 声明的变量为全局变量，并且会将该变量添加为全局对象的属性，但是 let 和 const 不会。<br>
<strong>（4）重复声明：</strong> var 声明变量时，可以重复声明变量，后声明的同名变量会覆盖之前声明的遍历。const 和 let 不允许重复声明变量。<br>
<strong>（5）暂时性死区：</strong> 在使用 let，const 命令声明变量之前，该变量都是不可用的。这在语法上，称为<strong>暂时性死区</strong>。使用 var 声明的变量不存在暂时性死区。<br>
<strong>（6）初始值设置：</strong> 在变量声明时，var 和 let 可以不用设置初始值。而 const 声明变量必须设置初始值。<br>
<strong>（7）指针指向：</strong> let 和 const 都是 ES6 新增的用于创建变量的语法。 let 创建的变量是可以更改指针指向（可以重新赋值）。但 const 声明的变量是不允许改变指针的指向。</p>
<table>
<thead>
<tr>
<th><strong>区别</strong></th>
<th><strong>var</strong></th>
<th><strong>let</strong></th>
<th><strong>const</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td>是否有块级作用域</td>
<td>×</td>
<td>✔️</td>
<td>✔️</td>
</tr>
<tr>
<td>是否存在变量提升</td>
<td>✔️</td>
<td>×</td>
<td>×</td>
</tr>
<tr>
<td>是否添加全局属性</td>
<td>✔️</td>
<td>×</td>
<td>×</td>
</tr>
<tr>
<td>能否重复声明变量</td>
<td>✔️</td>
<td>×</td>
<td>×</td>
</tr>
<tr>
<td>是否存在暂时性死区</td>
<td>×</td>
<td>✔️</td>
<td>✔️</td>
</tr>
<tr>
<td>是否必须设置初始值</td>
<td>×</td>
<td>×</td>
<td>✔️</td>
</tr>
<tr>
<td>能否改变指针指向</td>
<td>✔️</td>
<td>✔️</td>
<td>×</td>
</tr>
</tbody>
</table>
<h3 id="2-const对象的属性可以修改吗"><a class="markdownIt-Anchor" href="#2-const对象的属性可以修改吗">#</a> 2. const 对象的属性可以修改吗</h3>
<p>const 保证的并不是变量的值不能改动，而是变量指向的那个内存地址不能改动。对于基本类型的数据（数值、字符串、布尔值），其值就保存在变量指向的那个内存地址，因此等同于常量。</p>
<p>但对于引用类型的数据（主要是对象和数组）来说，变量指向数据的内存地址，保存的只是一个指针，const 只能保证这个指针是固定不变的，至于它指向的数据结构是不是可变的，就完全不能控制了。</p>
<h3 id="3-如果new一个箭头函数的会怎么样"><a class="markdownIt-Anchor" href="#3-如果new一个箭头函数的会怎么样">#</a> 3. 如果 new 一个箭头函数的会怎么样</h3>
<p>箭头函数是 ES6 中的提出来的，它没有 prototype，也没有自己的 this 指向，更不可以使用 arguments 参数，所以不能 new 一个箭头函数。</p>
<h3 id="4new操作符的实现步骤如下"><a class="markdownIt-Anchor" href="#4new操作符的实现步骤如下">#</a> 4.new 操作符的实现步骤如下：</h3>
<ol>
<li>在内存中创建一个新对象</li>
<li>将构造函数的作用域赋给新对象（也就是将对象的__proto__属性指向构造函数的 prototype 属性）</li>
<li>构造函数内部的 this 指向新对象（也就是为这个对象添加属性和方法）</li>
<li>执行构造函数内部的代码</li>
<li>如果构造函数返回非空对象，则返回该对象；否则，返回刚创建的新对象</li>
</ol>
<h3 id="5箭头函数与普通函数的区别"><a class="markdownIt-Anchor" href="#5箭头函数与普通函数的区别">#</a> 5. 箭头函数与普通函数的区别：</h3>
<ol>
<li>箭头函数比普通函数更简洁。</li>
<li>箭头函数没有自己的 this。</li>
<li>箭头函数继承的 this 永远不会改变。</li>
<li>call ()、apply ()、bind () 等方法不能改变箭头函数中 this 的指向。</li>
<li>箭头函数不能作为构造函数使用。</li>
<li>箭头函数没有自己的 arguments。</li>
</ol>
<h3 id="6-箭头函数的this指向哪里"><a class="markdownIt-Anchor" href="#6-箭头函数的this指向哪里">#</a> 6. 箭头函数的<strong> this</strong> 指向哪⾥？</h3>
<p>箭头函数不同于传统 JavaScript 中的函数，箭头函数并没有属于⾃⼰的 this，它所谓的 this 是捕获其所在上下⽂的 this 值，作为⾃⼰的 this 值，并且由于没有属于⾃⼰的 this，所以是不会被 new 调⽤的，这个所谓的 this 也不会被改变。</p>
<h3 id="7-proxy可以实现什么功能"><a class="markdownIt-Anchor" href="#7-proxy可以实现什么功能">#</a> 7. Proxy 可以实现什么功能？</h3>
<p>在 Vue3.0 中通过 Proxy 来替换原本的 Object.defineProperty 来实现数据响应式。</p>
<p>Proxy 是 ES6 中新增的功能，它可以用来自定义对象中的操作。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> p = <span class="keyword">new</span> <span class="title class_">Proxy</span>(target, handler)</span><br></pre></td></tr></table></figure>
<p>target 代表需要添加代理的对象，handler 用来自定义对象中的操作，比如可以用来自定义 set 或者 get 函数。</p>
<pre><code>在Vue3.0要使用proxy替换原本的API原因在于Proxy无需一层层递归为每一个属性添加代理，一次即可完成以上操作，性能上更好，并且原本的实现有一些数据更新不能见听到，但是Proxy可以完美见听到任何方式的数据改变，唯一的缺陷就是浏览器的兼容性不好。
</code></pre>
<h2 id="三javascript基础"><a class="markdownIt-Anchor" href="#三javascript基础">#</a> 三.JavaScript 基础</h2>
<h3 id="1map和object的区别"><a class="markdownIt-Anchor" href="#1map和object的区别">#</a> 1.map 和 Object 的区别</h3>
<table>
<thead>
<tr>
<th></th>
<th>Map</th>
<th>Object</th>
</tr>
</thead>
<tbody>
<tr>
<td>意外的键</td>
<td>Map 默认情况不包含任何键，只包含显式插入的键。</td>
<td>Object 有一个原型，原型链上的键名有可能和自己在对象上的设置的键名产生冲突。</td>
</tr>
<tr>
<td>键的类型</td>
<td>Map 的键可以是任意值，包括函数、对象或任意基本类型。</td>
<td>Object 的键必须是 String 或是 Symbol。</td>
</tr>
<tr>
<td>键的顺序</td>
<td>Map 中的 key 是有序的。因此，当迭代的时候， Map 对象以插入的顺序返回键值。</td>
<td>Object 的键是无序的</td>
</tr>
<tr>
<td>Size</td>
<td>Map 的键值对个数可以轻易地通过 size 属性获取</td>
<td>Object 的键值对个数只能手动计算</td>
</tr>
<tr>
<td>迭代</td>
<td>Map 是 iterable 的，所以可以直接被迭代。</td>
<td>迭代 Object 需要以某种方式获取它的键然后才能迭代。</td>
</tr>
<tr>
<td>性能</td>
<td>在频繁增删键值对的场景下表现更好。</td>
<td>在频繁添加和删除键值对的场景下未作出优化。</td>
</tr>
</tbody>
</table>
<h3 id="2map和weakmap的区别"><a class="markdownIt-Anchor" href="#2map和weakmap的区别">#</a> 2.map 和 weakMap 的区别</h3>
<p>(1)Map<br>
map 的本质是键值对的集合，但是普通的 Object 中的键值对中的键只能是字符串。而 ES6 提供的 Map 数据结构类似于对象，但是它的键不限制的范围，可以是任意类型，是一种更完善的 Hash 结构。如果 Map 的键是一个原始数据类型，只要两个键严格相同，就视为是同一个键。</p>
<p>Map 数据结构有以下操作方法：</p>
<ul>
<li><strong>size</strong>：  <code>map.size</code>  返回 Map 结构的成员总数。</li>
<li><strong>set(key,value)</strong>：设置键名 key 对应的键值 value，然后返回整个 Map 结构，如果 key 已经有值，则键值会被更新，否则就新生成该键。（因为返回的是当前 Map 对象，所以可以链式调用）</li>
<li><strong>get(key)</strong>：该方法读取 key 对应的键值，如果找不到 key，返回 undefined。</li>
<li><strong>has(key)</strong>：该方法返回一个布尔值，表示某个键是否在当前 Map 对象中。</li>
<li><strong>delete(key)</strong>：该方法删除某个键，返回 true，如果删除失败，返回 false。</li>
<li><strong>clear()</strong>：map.clear () 清除所有成员，没有返回值。</li>
</ul>
<p>Map 结构原生提供是三个遍历器生成函数和一个遍历方法</p>
<ul>
<li>keys ()：返回键名的遍历器。</li>
<li>values ()：返回键值的遍历器。</li>
<li>entries ()：返回所有成员的遍历器。</li>
<li>forEach ()：遍历 Map 的所有成员。<br>
(2)WeakMap<br>
WeakMap 对象也是一组键值对的集合，其中的键是弱引用的。其键必须是对象，原始数据类型不能作为 key 值，而值可以是任意的。</li>
</ul>
<p>该对象也有以下几种方法：</p>
<ul>
<li><strong>set(key,value)</strong>：设置键名 key 对应的键值 value，然后返回整个 Map 结构，如果 key 已经有值，则键值会被更新，否则就新生成该键。（因为返回的是当前 Map 对象，所以可以链式调用）</li>
<li><strong>get(key)</strong>：该方法读取 key 对应的键值，如果找不到 key，返回 undefined。</li>
<li><strong>has(key)</strong>：该方法返回一个布尔值，表示某个键是否在当前 Map 对象中。</li>
<li><strong>delete(key)</strong>：该方法删除某个键，返回 true，如果删除失败，返回 false。</li>
</ul>
<p>其 clear () 方法已经被弃用，所以可以通过创建一个空的 WeakMap 并替换原对象来实现清除。<br>
WeakMap 的设计目的在于，有时想在某个对象上面存放一些数据，但是这会形成对于这个对象的引用。一旦不再需要这两个对象，就必须手动删除这个引用，否则垃圾回收机制就不会释放对象占用的内存。<br>
而 WeakMap 的<strong>键名所引用的对象都是弱引用</strong>，即垃圾回收机制不将该引用考虑在内。因此，只要所引用的对象的其他引用都被清除，垃圾回收机制就会释放该对象所占用的内存。也就是说，一旦不再需要，WeakMap 里面的<strong>键名对象和所对应的键值对会自动消失，不用手动删除引用</strong>。<br>
<strong>总结：</strong></p>
<ul>
<li>Map 数据结构。它类似于对象，也是键值对的集合，但是 “键” 的范围不限于字符串，各种类型的值（包括对象）都可以当作键。</li>
<li>WeakMap 结构与 Map 结构类似，也是用于生成键值对的集合。但是 WeakMap 只接受对象作为键名（ null 除外），不接受其他类型的值作为键名。而且 WeakMap 的键名所指向的对象，不计入垃圾回收机制。</li>
</ul>
<h3 id="3-数组有哪些原生方法"><a class="markdownIt-Anchor" href="#3-数组有哪些原生方法">#</a> 3. 数组有哪些原生方法？</h3>
<ul>
<li>数组和字符串的转换方法：toString ()、toLocalString ()、join () 其中 join () 方法可以指定转换为字符串时的分隔符。</li>
<li>数组尾部操作的方法 pop () 和 push ()，push 方法可以传入多个参数。</li>
<li>数组首部操作的方法 shift () 和 unshift () 重排序的方法 reverse () 和 sort ()，sort () 方法可以传入一个函数来进行比较，传入前后两个值，如果返回值为正数，则交换两个参数的位置。</li>
<li>数组连接的方法 concat () ，返回的是拼接好的数组，不影响原数组。</li>
<li>数组截取办法 slice ()，用于截取数组中的一部分返回，不影响原数组。</li>
<li>数组插入方法 splice ()，影响原数组查找特定项的索引的方法，indexOf () 和 lastIndexOf () 迭代方法 every ()、some ()、filter ()、map () 和 forEach () 方法</li>
<li>数组归并方法 reduce () 和 reduceRight () 方法</li>
</ul>
<h3 id="4-什么是-dom-和-bom"><a class="markdownIt-Anchor" href="#4-什么是-dom-和-bom">#</a> 4. 什么是 DOM 和 BOM？</h3>
<ul>
<li>DOM 指的是文档对象模型，它指的是把文档当做一个对象，这个对象主要定义了处理网页内容的方法和接口。</li>
<li>BOM 指的是浏览器对象模型，它指的是把浏览器当做一个对象来对待，这个对象主要定义了与浏览器进行交互的法和接口。BOM 的核心是 window，而 window 对象具有双重角色，它既是通过 js 访问浏览器窗口的一个接口，又是一个 Global（全局）对象。这意味着在网页中定义的任何对象，变量和函数，都作为全局对象的一个属性或者方法存在。window 对象含有 location 对象、navigator 对象、screen 对象等子对象，并且 DOM 的最根本的对象 document 对象也是 BOM 的 window 对象的子对象。</li>
</ul>
<h3 id="5-对ajax的理解实现一个ajax请求"><a class="markdownIt-Anchor" href="#5-对ajax的理解实现一个ajax请求">#</a> 5. 对 AJAX 的理解，实现一个 AJAX 请求</h3>
<p>AJAX 是 Asynchronous JavaScript and XML 的缩写，指的是通过 JavaScript 的 异步通信，从服务器获取 XML 文档从中提取数据，再更新当前网页的对应部分，而不用刷新整个网页。</p>
<p>创建 AJAX 请求的步骤：</p>
<ul>
<li><strong>创建一个 XMLHttpRequest 对象。</strong></li>
<li>在这个对象上<strong>使用 open 方法创建一个 HTTP 请求</strong>，open 方法所需要的参数是请求的方法、请求的地址、是否异步和用户的认证信息。</li>
<li>在发起请求前，可以为这个对象<strong>添加一些信息和监听函数</strong>。比如说可以通过 setRequestHeader 方法来为请求添加头信息。还可以为这个对象添加一个状态监听函数。一个 XMLHttpRequest 对象一共有 5 个状态，当它的状态变化时会触发 onreadystatechange 事件，可以通过设置监听函数，来处理请求成功后的结果。当对象的 readyState 变为 4 的时候，代表服务器返回的数据接收完成，这个时候可以通过判断请求的状态，如果状态是 2xx 或者 304 的话则代表返回正常。这个时候就可以通过 response 中的数据来对页面进行更新了。</li>
<li>当对象的属性和监听函数设置完成后，最后调<strong>用 sent 方法来向服务器发起请求</strong>，可以传入参数作为发送的数据体。</li>
</ul>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">const SERVER_URL = &quot;/server&quot;;</span><br><span class="line">let xhr = new XMLHttpRequest();</span><br><span class="line">// 创建 Http 请求</span><br><span class="line">xhr.open(&quot;GET&quot;, url, true);</span><br><span class="line">// 设置状态监听函数</span><br><span class="line">xhr.onreadystatechange = function() &#123;</span><br><span class="line">  if (this.readyState !== 4) return;</span><br><span class="line">  // 当请求成功时</span><br><span class="line">  if (this.status === 200) &#123;</span><br><span class="line">    handle(this.response);</span><br><span class="line">  &#125; else &#123;</span><br><span class="line">    console.error(this.statusText);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line">// 设置请求失败时的监听函数</span><br><span class="line">xhr.onerror = function() &#123;</span><br><span class="line">  console.error(this.statusText);</span><br><span class="line">&#125;;</span><br><span class="line">// 设置请求头信息</span><br><span class="line">xhr.responseType = &quot;json&quot;;</span><br><span class="line">xhr.setRequestHeader(&quot;Accept&quot;, &quot;application/json&quot;);</span><br><span class="line">// 发送 Http 请求</span><br><span class="line">xhr.send(null);</span><br></pre></td></tr></table></figure>
<p>使用 Promise 封装 AJAX：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line">// promise 封装实现：</span><br><span class="line">function getJSON(url) &#123;</span><br><span class="line">  // 创建一个 promise 对象</span><br><span class="line">  let promise = new Promise(function(resolve, reject) &#123;</span><br><span class="line">    let xhr = new XMLHttpRequest();</span><br><span class="line">    // 新建一个 http 请求</span><br><span class="line">    xhr.open(&quot;GET&quot;, url, true);</span><br><span class="line">    // 设置状态的监听函数</span><br><span class="line">    xhr.onreadystatechange = function() &#123;</span><br><span class="line">      if (this.readyState !== 4) return;</span><br><span class="line">      // 当请求成功或失败时，改变 promise 的状态</span><br><span class="line">      if (this.status === 200) &#123;</span><br><span class="line">        resolve(this.response);</span><br><span class="line">      &#125; else &#123;</span><br><span class="line">        reject(new Error(this.statusText));</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;;</span><br><span class="line">    // 设置错误监听函数</span><br><span class="line">    xhr.onerror = function() &#123;</span><br><span class="line">      reject(new Error(this.statusText));</span><br><span class="line">    &#125;;</span><br><span class="line">    // 设置响应的数据类型</span><br><span class="line">    xhr.responseType = &quot;json&quot;;</span><br><span class="line">    // 设置请求头信息</span><br><span class="line">    xhr.setRequestHeader(&quot;Accept&quot;, &quot;application/json&quot;);</span><br><span class="line">    // 发送 http 请求</span><br><span class="line">    xhr.send(null);</span><br><span class="line">  &#125;);</span><br><span class="line">  return promise;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="20-常见的dom操作有哪些"><a class="markdownIt-Anchor" href="#20-常见的dom操作有哪些">#</a> 20. 常见的 DOM 操作有哪些</h3>
<h4 id="1dom-节点的获取"><a class="markdownIt-Anchor" href="#1dom-节点的获取">#</a> 1）DOM 节点的获取</h4>
<p>DOM 节点的获取的 API 及使用：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">getElementById // 按照 id 查询</span><br><span class="line">getElementsByTagName // 按照标签名查询</span><br><span class="line">getElementsByClassName // 按照类名查询</span><br><span class="line">querySelectorAll // 按照 css 选择器查询</span><br><span class="line"></span><br><span class="line">// 按照 id 查询</span><br><span class="line">var imooc = document.getElementById(&#x27;imooc&#x27;) // 查询到 id 为 imooc 的元素</span><br><span class="line">// 按照标签名查询</span><br><span class="line">var pList = document.getElementsByTagName(&#x27;p&#x27;)  // 查询到标签为 p 的集合</span><br><span class="line">console.log(divList.length)</span><br><span class="line">console.log(divList[0])</span><br><span class="line">// 按照类名查询</span><br><span class="line">var moocList = document.getElementsByClassName(&#x27;mooc&#x27;) // 查询到类名为 mooc 的集合</span><br><span class="line">// 按照 css 选择器查询</span><br><span class="line">var pList = document.querySelectorAll(&#x27;.mooc&#x27;) // 查询到类名为 mooc 的集合</span><br></pre></td></tr></table></figure>
<h4 id="2dom-节点的创建"><a class="markdownIt-Anchor" href="#2dom-节点的创建">#</a> 2）DOM 节点的创建</h4>
<p>** 创建一个新节点，并把它添加到指定节点的后面。** 已知的 HTML 结构如下：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">&lt;html&gt;</span><br><span class="line">  &lt;head&gt;</span><br><span class="line">    &lt;title&gt;DEMO&lt;/title&gt;</span><br><span class="line">  &lt;/head&gt;</span><br><span class="line">  &lt;body&gt;</span><br><span class="line">    &lt;div id=&quot;container&quot;&gt; </span><br><span class="line">      &lt;h1 id=&quot;title&quot;&gt;我是标题&lt;/h1&gt;</span><br><span class="line">    &lt;/div&gt;   </span><br><span class="line">  &lt;/body&gt;</span><br><span class="line">&lt;/html&gt;</span><br></pre></td></tr></table></figure>
<p>要求添加一个有内容的 span 节点到 id 为 title 的节点后面，做法就是：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">// 首先获取父节点</span><br><span class="line">var container = document.getElementById(&#x27;container&#x27;)</span><br><span class="line">// 创建新节点</span><br><span class="line">var targetSpan = document.createElement(&#x27;span&#x27;)</span><br><span class="line">// 设置 span 节点的内容</span><br><span class="line">targetSpan.innerHTML = &#x27;hello world&#x27;</span><br><span class="line">// 把新创建的元素塞进父节点里去</span><br><span class="line">container.appendChild(targetSpan)</span><br></pre></td></tr></table></figure>
<h4 id="3dom-节点的删除"><a class="markdownIt-Anchor" href="#3dom-节点的删除">#</a> 3）DOM 节点的删除</h4>
<p>** 删除指定的 DOM 节点，** 已知的 HTML 结构如下：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">&lt;html&gt;</span><br><span class="line">  &lt;head&gt;</span><br><span class="line">    &lt;title&gt;DEMO&lt;/title&gt;</span><br><span class="line">  &lt;/head&gt;</span><br><span class="line">  &lt;body&gt;</span><br><span class="line">    &lt;div id=&quot;container&quot;&gt; </span><br><span class="line">      &lt;h1 id=&quot;title&quot;&gt;我是标题&lt;/h1&gt;</span><br><span class="line">    &lt;/div&gt;   </span><br><span class="line">  &lt;/body&gt;</span><br><span class="line">&lt;/html&gt;</span><br></pre></td></tr></table></figure>
<p>需要删除 id 为 title 的元素，做法是：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">// 获取目标元素的父元素</span><br><span class="line">var container = document.getElementById(&#x27;container&#x27;)</span><br><span class="line">// 获取目标元素</span><br><span class="line">var targetNode = document.getElementById(&#x27;title&#x27;)</span><br><span class="line">// 删除目标元素</span><br><span class="line">container.removeChild(targetNode)</span><br></pre></td></tr></table></figure>
<p>或者通过子节点数组来完成删除：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">// 获取目标元素的父元素</span><br><span class="line">var container = document.getElementById(&#x27;container&#x27;)</span><br><span class="line">// 获取目标元素</span><br><span class="line">var targetNode = container.childNodes[1]</span><br><span class="line">// 删除目标元素</span><br><span class="line">container.removeChild(targetNode)</span><br></pre></td></tr></table></figure>
<h4 id="4修改-dom-元素"><a class="markdownIt-Anchor" href="#4修改-dom-元素">#</a> 4）修改 DOM 元素</h4>
<p>修改 DOM 元素这个动作可以分很多维度，比如说移动 DOM 元素的位置，修改 DOM 元素的属性等。</p>
<p>** 将指定的两个 DOM 元素交换位置，** 已知的 HTML 结构如下：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">&lt;html&gt;</span><br><span class="line">  &lt;head&gt;</span><br><span class="line">    &lt;title&gt;DEMO&lt;/title&gt;</span><br><span class="line">  &lt;/head&gt;</span><br><span class="line">  &lt;body&gt;</span><br><span class="line">    &lt;div id=&quot;container&quot;&gt; </span><br><span class="line">      &lt;h1 id=&quot;title&quot;&gt;我是标题&lt;/h1&gt;</span><br><span class="line">      &lt;p id=&quot;content&quot;&gt;我是内容&lt;/p&gt;</span><br><span class="line">    &lt;/div&gt;   </span><br><span class="line">  &lt;/body&gt;</span><br><span class="line">&lt;/html&gt;</span><br></pre></td></tr></table></figure>
<p>现在需要调换 title 和 content 的位置，可以考虑 insertBefore 或者 appendChild：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">// 获取父元素</span><br><span class="line">var container = document.getElementById(&#x27;container&#x27;)   </span><br><span class="line"> </span><br><span class="line">// 获取两个需要被交换的元素</span><br><span class="line">var title = document.getElementById(&#x27;title&#x27;)</span><br><span class="line">var content = document.getElementById(&#x27;content&#x27;)</span><br><span class="line">// 交换两个元素，把 content 置于 title 前面</span><br><span class="line">container.insertBefore(content, title)</span><br></pre></td></tr></table></figure>
<h3 id="25-forin和forof的区别"><a class="markdownIt-Anchor" href="#25-forin和forof的区别">#</a> 25. for…in 和 for…of 的区别</h3>
<p>for…of 是 ES6 新增的遍历方式，允许遍历一个含有 iterator 接口的数据结构（数组、对象等）并且返回各项的值，和 ES3 中的 for…in 的区别如下</p>
<ul>
<li>for…of 遍历获取的是对象的键值，for…in 获取的是对象的键名；</li>
<li>for… in 会遍历对象的整个原型链，性能非常差不推荐使用，而 for … of 只遍历当前对象不会遍历原型链；</li>
<li>对于数组的遍历，for…in 会返回数组中所有可枚举的属性 (包括原型链上可枚举的属性)，for…of 只返回数组的下标对应的属性值；</li>
</ul>
<p><strong>总结</strong>: for…in 循环主要是为了遍历对象而生，不适用于遍历数组；for…of 循环可以用来遍历数组、类数组对象，字符串、Set、Map 以及 Generator 对象。</p>
<h3 id="26-fentch-ajax-axios的区别"><a class="markdownIt-Anchor" href="#26-fentch-ajax-axios的区别">#</a> 26. fentch、Ajax、axios 的区别</h3>
<p>Ajax (异步 js 和 xml)，是指一种创建交互式网页应用的网页开发技术，它是一种在无需重新加载整个网页的情况下，能够更新部分网页的技术。通过在后台的服务器进行少量数据交换，Ajax 可以使网页实现也不更新。穿透的网页如果更新内容，必须重载整个网页页面。<br>
<strong>缺点</strong>:</p>
<ul>
<li>本身是针对 MVC 变成，不符合前端 MVVM 的浪潮。</li>
<li>基于原生 XHR 开发，XHR 本身的架构不清晰。</li>
<li>不符合关注分离的原则。</li>
<li>配置和调用方式非常混乱，而且基于事件的异步模型不友好。</li>
</ul>
<p><strong>Fetch</strong>:<br>
 是 AJAX 的替代品，是在 ES6 出现的，使用了 es6 的 promise 对象。Fetch 是基于 promise 设计的。Fetch 的代码结构比起 ajax 简单。<br>
<strong>fetch 不是 ajax 的进一步封装，而是原生 js，没有使用 XMLHttpRequest 对象</strong><br>
<strong>优点:</strong></p>
<ul>
<li>语法简洁，更加语义化。</li>
<li>基于标准 Promise 实现，支持 async/await</li>
<li>更加底层，提供丰富的 API (request，response)</li>
<li>脱离了 XHR，是 ES 规范里新的实现方式。<br>
<strong>缺点:</strong></li>
<li>fetch 只对网络请求报错，对 400,500 都当做请求成功的请求，服务器返回 400,500 错误码时不会 reject，只有网络错误这些导致请求不能完成时，fetch 才会被 reject。</li>
<li>fetch 默认不会带 cookie，需要添加配置项:fetch (url，{credentials:‘include’})</li>
<li>fetch 不支持 abort，不支持超时控制，使用 setTimeout 及 promise.reject 的实现的超时控制并不能阻止请求过程继续在后台进行，造成流量浪费。</li>
<li>fetch 没办法元素检测请求的进度，而 XHR 可以。</li>
</ul>
<p><strong>Axios</strong><br>
 是一种基于 Promise 封装的 HTTP 客服端，其特点如下:</p>
<ul>
<li>浏览器发起 XMLHttpRequests 请求</li>
<li>node 端发起 http 请求</li>
<li>支持 PromiseAPI</li>
<li>监听请求和返回</li>
<li>对请求和返回进行转化</li>
<li>取消请求</li>
<li>自动转换 json 数据</li>
<li>客户端支持抵御 XSRF 攻击</li>
</ul>
<h3 id="28-数组的遍历方法有哪些"><a class="markdownIt-Anchor" href="#28-数组的遍历方法有哪些">#</a> 28. 数组的遍历方法有哪些</h3>
<table>
<thead>
<tr>
<th><strong>方法</strong></th>
<th><strong>是否改变原数组</strong></th>
<th><strong>特点</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td>forEach()</td>
<td>否</td>
<td>数组方法，不改变原数组，没有返回值</td>
</tr>
<tr>
<td>map()</td>
<td>否</td>
<td>数组方法，不改变原数组，有返回值，可链式调用</td>
</tr>
<tr>
<td>filter()</td>
<td>否</td>
<td>数组方法，过滤数组，返回包含符合条件的元素的数组，可链式调用</td>
</tr>
<tr>
<td>for…of</td>
<td>否</td>
<td>for…of 遍历具有 Iterator 迭代器的对象的属性，返回的是数组的元素、对象的属性值，不能遍历普通的 obj 对象，将异步循环变成同步循环</td>
</tr>
<tr>
<td>every () 和 some ()</td>
<td>否</td>
<td>数组方法，some () 只要有一个是 true，便返回 true；而 every () 只要有一个是 false，便返回 false.</td>
</tr>
<tr>
<td>find () 和 findIndex ()</td>
<td>否</td>
<td>数组方法，find () 返回的是第一个符合条件的值；findIndex () 返回的是第一个返回条件的值的索引值</td>
</tr>
<tr>
<td>reduce () 和 reduceRight ()</td>
<td>否</td>
<td>数组方法，reduce () 对数组正序操作；reduceRight () 对数组逆序操作</td>
</tr>
</tbody>
</table>
<p>遍历方法的详细解释：<span class="exturl" data-url="aHR0cHM6Ly9jdWdnei5ibG9nLmNzZG4ubmV0L2FydGljbGUvZGV0YWlscy8xMDc2NDk1NDk=">《细数 JavaScript 中那些遍历和循环》</span></p>
<h3 id="29foreach和map方法有什么区别"><a class="markdownIt-Anchor" href="#29foreach和map方法有什么区别">#</a> 29.forEach 和 map 方法有什么区别</h3>
<p>这个方法都是用来遍历数组的，两者区别如下:</p>
<ul>
<li>forEach () 方法会针对每一个元素执行提供的函数，对数据的操作会改变原数组，该方法没有返回值；</li>
<li>map () 方法不会改变原数组的值，返回一个新数组，新数组中的值为原数组调用函数处理之后的值。</li>
</ul>
<h3 id="30objectis与比较操作符-区别"><a class="markdownIt-Anchor" href="#30objectis与比较操作符-区别">#</a> 30.Object.is 与比较操作符’=<mark>‘、’</mark>‘区别？</h3>
<ul>
<li>使用双等号 (==) 进行相等判断时，如果两边的类型不一致，则会进行强制类型转换后进行比较。</li>
<li>三等号 (===) 进行相等判断时，如果两边类型不一致，不会做强制类型转换，直接返回 false。</li>
<li>使用 Object.is 进行相等判断时，一般情况下和三等号判断相同了，他处理了一些特殊的情况，比如 - 0，+0 不再相等，两个 Nan 相等的。</li>
</ul>
<h3 id="30垃圾回收机制"><a class="markdownIt-Anchor" href="#30垃圾回收机制">#</a> 30. 垃圾回收机制</h3>
<p>Js 代码运行时，需要分配内存空间来存储变量和值，当变量不参与运行时，就需要系统收回被占用的内存空间，这就是垃圾回收机制。</p>
<h3 id="31promise的理解"><a class="markdownIt-Anchor" href="#31promise的理解">#</a> 31.Promise 的理解</h3>
<p>Promise 是异步编程的一种解决方案，它是一个对象，可以获取异步操作的消息，他的出现大大改善了异步编程的困境，避免了回调地狱，它比传统的解决方案回调函数和事件更合理和更强大。<br>
(1) Promise 的实例三个状态：</p>
<ul>
<li>Pending (进行中)</li>
<li>Resolve (已完成)</li>
<li>Rejected (已拒绝)<br>
(2) Promise 两个过程:</li>
<li>pending -&gt; fulfilled:Resolve (已完成)</li>
<li>pending -&gt; rejected:Rejected (已拒绝)<br>
 Promise 的特点:</li>
<li>一旦状态改变就不会再变，任何时候都可以得到这个结果。<br>
缺点:</li>
<li>无法取消 Promise，一旦新建它就会立即执行，无法中途取消。</li>
<li>如果不设置回调函数，Promise 内部抛出的错误，不会反映到外部。</li>
<li>处于 pending 状态时，无法得知目前进展到哪一个阶段。</li>
</ul>
<h3 id="32promise方法"><a class="markdownIt-Anchor" href="#32promise方法">#</a> 32.Promise 方法</h3>
<p><code>.then()</code>  接受第一个参数 resolved 时调用，成功调用。<br>
 <code>.catch()</code>  接受第二个参数 rejected 时调用，失败调用。<br>
 <code>.all()</code>  是可以完成并行任务，接收一个数组，数组每一项都是一个 promise 对象。当数组中所有的 promise 的状态都达到 resolved 的时候，all 方法的状态就会变成 resolved, 如果有一个状态变成了 rejected 就变成了 rejected。<br>
 <code>race()</code>  是可以完成并行任务，接收一个数组，数组每一项都是一个 promise 对象。当数组中一个的 promise 的状态都达到 resolved 的时候，race 方法的状态就会变成 resolved, 如果有一个状态变成了 rejected 就变成了 rejected。<br>
 <code>finally()</code>  不管 Promise 对象最后状态如何，都会执行。</p>
<h3 id="33对asyncawait的理解"><a class="markdownIt-Anchor" href="#33对asyncawait的理解">#</a> 33. 对 async/await 的理解</h3>
<p>async/await 其实是 Generator 的语法糖，它是为优化 then 链而开发出来的。从字面上来看，async 是‘异步’，await 是‘等待’。<br>
async 函数返回的是一个 Promise 对象。<br>
await 是什么？</p>
<ul>
<li>如果它等到的不是一个 Promise 对象，那 await 表达式的运算结果就是它等到的东西。</li>
<li>如果它等到的是一个 Promise 对象，await 就忙起来了，它会阻塞后面的代码，等着 Promise 对象 resolve，然后得到 reslove 的值，作为 await 表达式的运算结果。</li>
</ul>
<h3 id="34-asyncawait对比promise的优势"><a class="markdownIt-Anchor" href="#34-asyncawait对比promise的优势">#</a> 34. async/await 对比 Promise 的优势</h3>
<ul>
<li>代码读起来更加同步，Promise 虽然摆脱了回调地狱，但是 then 的链式调⽤也会带来额外的阅读负担</li>
<li>Promise 传递中间值⾮常麻烦，⽽ async/await ⼏乎是同步的写法，⾮常优雅</li>
<li>错误处理友好，async/await 可以⽤成熟的 try/catch，Promise 的错误捕获⾮常冗余</li>
<li>调试友好，Promise 的调试很差，由于没有代码块，你不能在⼀个返回表达式的箭头函数中设置断点，如果你在⼀个.then 代码块中使⽤调试器的步进 (step-over) 功能，调试器并不会进⼊后续的.then 代码块，因为调试器只能跟踪同步代码的每⼀步。</li>
</ul>
<h3 id="深拷贝和浅拷贝"><a class="markdownIt-Anchor" href="#深拷贝和浅拷贝">#</a> 深拷贝和浅拷贝</h3>

      <div class="tags">
          <a href="/blog/tags/%E5%B0%91%E6%97%B6%E8%AF%B5%E8%AF%97%E4%B9%A6/" rel="tag"><i class="ic i-tag"></i> 少时诵诗书</a>
      </div>
  </div>

   <footer>

    <div class="meta">
  <span class="item">
    <span class="icon">
      <i class="ic i-calendar-check"></i>
    </span>
    <span class="text">更新于</span>
    <time title="修改时间：2023-08-18 15:54:26" itemprop="dateModified" datetime="2023-08-18T15:54:26+08:00">2023-08-18</time>
  </span>
</div>

      
<div class="reward">
  <button><i class="ic i-heartbeat"></i> 赞赏</button>
  <p>请我喝[茶]~(￣▽￣)~*</p>
  <div id="qr">
      
      <div>
        <img data-src="/blog/images/wechatpay.png" alt="宋胖子 微信支付">
        <p>微信支付</p>
      </div>
      
      <div>
        <img data-src="/blog/images/alipay.png" alt="宋胖子 支付宝">
        <p>支付宝</p>
      </div>
      
      <div>
        <img data-src="/blog/images/paypal.png" alt="宋胖子 贝宝">
        <p>贝宝</p>
      </div>
  </div>
</div>

      

<div id="copyright">
<ul>
  <li class="author">
    <strong>本文作者： </strong>宋胖子 <i class="ic i-at"><em>@</em></i>宋胖子
  </li>
  <li class="link">
    <strong>本文链接：</strong>
    <a href="https://song-ruipeng.gitee.io/blog/2023/05/17/%E5%9B%9B.JS/" title="JS">https://song-ruipeng.gitee.io/blog/2023/05/17/四.JS/</a>
  </li>
  <li class="license">
    <strong>版权声明： </strong>本站所有文章除特别声明外，均采用 <span class="exturl" data-url="aHR0cHM6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL2J5LW5jLXNhLzQuMC9kZWVkLnpo"><i class="ic i-creative-commons"><em>(CC)</em></i>BY-NC-SA</span> 许可协议。转载请注明出处！
  </li>
</ul>
</div>

  </footer>

</article>

  </div>
  

<div class="post-nav">
    <div class="item left">
      

  <a href="/blog/2023/05/05/%E4%B8%89.Css/" itemprop="url" rel="prev" data-background-image=" https:&#x2F;&#x2F;cancan-wx.oss-cn-hangzhou.aliyuncs.com&#x2F;bg&#x2F;6833939bly1gipevarprfj20zk0m8npd.jpg" title="CSS">
  <span class="type">上一篇</span>
  <span class="category"><i class="ic i-flag"></i> 我的日志</span>
  <h3>CSS</h3>
  </a>

    </div>
    <div class="item right">
      

  <a href="/blog/2023/06/12/%E4%BA%94.template/" itemprop="url" rel="next" data-background-image=" https:&#x2F;&#x2F;cancan-wx.oss-cn-hangzhou.aliyuncs.com&#x2F;bg&#x2F;6833939bly1giciuv0socj20zk0m8qes.jpg" title="Template">
  <span class="type">下一篇</span>
  <span class="category"><i class="ic i-flag"></i> 我的日志</span>
  <h3>Template</h3>
  </a>

    </div>
</div>

  
  <div class="wrap" id="comments"></div>


        </div>
        <div id="sidebar">
          

<div class="inner">

  <div class="panels">
    <div class="inner">
      <div class="contents panel pjax" data-title="文章目录">
          <ol class="toc"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%9B%9Bjs"><span class="toc-number">1.</span> <span class="toc-text"> 四.JS</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#41-js%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B%E6%9C%89%E5%93%AA%E4%BA%9B%E4%BB%96%E4%BB%AC%E7%9A%84%E5%8C%BA%E5%88%AB%E6%98%AF%E4%BB%80%E4%B9%88"><span class="toc-number">2.</span> <span class="toc-text"> 4.1 JS 数据类型有哪些，他们的区别是什么？</span></a><ol class="toc-child"><li class="toc-item toc-level-6"><a class="toc-link" href="#%E7%AD%94"><span class="toc-number">2.0.0.1.</span> <span class="toc-text"> 答:</span></a></li></ol></li></ol></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B%E6%A3%80%E6%B5%8B%E7%9A%84%E6%96%B9%E5%BC%8F%E6%9C%89%E5%93%AA%E4%BA%9B"><span class="toc-number">3.</span> <span class="toc-text"> 2. 数据类型检测的方式有哪些</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3-%E5%88%A4%E6%96%AD%E6%95%B0%E7%BB%84%E7%9A%84%E6%96%B9%E5%BC%8F%E6%9C%89%E5%93%AA%E4%BA%9B"><span class="toc-number">4.</span> <span class="toc-text"> 3. 判断数组的方式有哪些？</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#4-undefined%E5%92%8Cnull"><span class="toc-number">5.</span> <span class="toc-text"> 4. Undefined 和 Null</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#7-%E4%B8%BA%E4%BB%80%E4%B9%880102-03%E5%A6%82%E4%BD%95%E8%AE%A9%E5%85%B6%E7%9B%B8%E7%AD%89"><span class="toc-number">6.</span> <span class="toc-text"> 7. 为什么 0.1+0.2 ! &#x3D;&#x3D; 0.3，如何让其相等</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BA%8C-es6"><span class="toc-number"></span> <span class="toc-text"> 二、ES6</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#1-let-const-var%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-number">1.</span> <span class="toc-text"> 1. let、const、var 的区别</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-const%E5%AF%B9%E8%B1%A1%E7%9A%84%E5%B1%9E%E6%80%A7%E5%8F%AF%E4%BB%A5%E4%BF%AE%E6%94%B9%E5%90%97"><span class="toc-number">2.</span> <span class="toc-text"> 2. const 对象的属性可以修改吗</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3-%E5%A6%82%E6%9E%9Cnew%E4%B8%80%E4%B8%AA%E7%AE%AD%E5%A4%B4%E5%87%BD%E6%95%B0%E7%9A%84%E4%BC%9A%E6%80%8E%E4%B9%88%E6%A0%B7"><span class="toc-number">3.</span> <span class="toc-text"> 3. 如果 new 一个箭头函数的会怎么样</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#4new%E6%93%8D%E4%BD%9C%E7%AC%A6%E7%9A%84%E5%AE%9E%E7%8E%B0%E6%AD%A5%E9%AA%A4%E5%A6%82%E4%B8%8B"><span class="toc-number">4.</span> <span class="toc-text"> 4.new 操作符的实现步骤如下：</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#5%E7%AE%AD%E5%A4%B4%E5%87%BD%E6%95%B0%E4%B8%8E%E6%99%AE%E9%80%9A%E5%87%BD%E6%95%B0%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-number">5.</span> <span class="toc-text"> 5. 箭头函数与普通函数的区别：</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#6-%E7%AE%AD%E5%A4%B4%E5%87%BD%E6%95%B0%E7%9A%84this%E6%8C%87%E5%90%91%E5%93%AA%E9%87%8C"><span class="toc-number">6.</span> <span class="toc-text"> 6. 箭头函数的 this 指向哪⾥？</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#7-proxy%E5%8F%AF%E4%BB%A5%E5%AE%9E%E7%8E%B0%E4%BB%80%E4%B9%88%E5%8A%9F%E8%83%BD"><span class="toc-number">7.</span> <span class="toc-text"> 7. Proxy 可以实现什么功能？</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%B8%89javascript%E5%9F%BA%E7%A1%80"><span class="toc-number"></span> <span class="toc-text"> 三.JavaScript 基础</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#1map%E5%92%8Cobject%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-number">1.</span> <span class="toc-text"> 1.map 和 Object 的区别</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2map%E5%92%8Cweakmap%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-number">2.</span> <span class="toc-text"> 2.map 和 weakMap 的区别</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3-%E6%95%B0%E7%BB%84%E6%9C%89%E5%93%AA%E4%BA%9B%E5%8E%9F%E7%94%9F%E6%96%B9%E6%B3%95"><span class="toc-number">3.</span> <span class="toc-text"> 3. 数组有哪些原生方法？</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#4-%E4%BB%80%E4%B9%88%E6%98%AF-dom-%E5%92%8C-bom"><span class="toc-number">4.</span> <span class="toc-text"> 4. 什么是 DOM 和 BOM？</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#5-%E5%AF%B9ajax%E7%9A%84%E7%90%86%E8%A7%A3%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AAajax%E8%AF%B7%E6%B1%82"><span class="toc-number">5.</span> <span class="toc-text"> 5. 对 AJAX 的理解，实现一个 AJAX 请求</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#20-%E5%B8%B8%E8%A7%81%E7%9A%84dom%E6%93%8D%E4%BD%9C%E6%9C%89%E5%93%AA%E4%BA%9B"><span class="toc-number">6.</span> <span class="toc-text"> 20. 常见的 DOM 操作有哪些</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#1dom-%E8%8A%82%E7%82%B9%E7%9A%84%E8%8E%B7%E5%8F%96"><span class="toc-number">6.1.</span> <span class="toc-text"> 1）DOM 节点的获取</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#2dom-%E8%8A%82%E7%82%B9%E7%9A%84%E5%88%9B%E5%BB%BA"><span class="toc-number">6.2.</span> <span class="toc-text"> 2）DOM 节点的创建</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#3dom-%E8%8A%82%E7%82%B9%E7%9A%84%E5%88%A0%E9%99%A4"><span class="toc-number">6.3.</span> <span class="toc-text"> 3）DOM 节点的删除</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#4%E4%BF%AE%E6%94%B9-dom-%E5%85%83%E7%B4%A0"><span class="toc-number">6.4.</span> <span class="toc-text"> 4）修改 DOM 元素</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#25-forin%E5%92%8Cforof%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-number">7.</span> <span class="toc-text"> 25. for…in 和 for…of 的区别</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#26-fentch-ajax-axios%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-number">8.</span> <span class="toc-text"> 26. fentch、Ajax、axios 的区别</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#28-%E6%95%B0%E7%BB%84%E7%9A%84%E9%81%8D%E5%8E%86%E6%96%B9%E6%B3%95%E6%9C%89%E5%93%AA%E4%BA%9B"><span class="toc-number">9.</span> <span class="toc-text"> 28. 数组的遍历方法有哪些</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#29foreach%E5%92%8Cmap%E6%96%B9%E6%B3%95%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB"><span class="toc-number">10.</span> <span class="toc-text"> 29.forEach 和 map 方法有什么区别</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#30objectis%E4%B8%8E%E6%AF%94%E8%BE%83%E6%93%8D%E4%BD%9C%E7%AC%A6-%E5%8C%BA%E5%88%AB"><span class="toc-number">11.</span> <span class="toc-text"> 30.Object.is 与比较操作符’&#x3D;‘、’‘区别？</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#30%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6%E6%9C%BA%E5%88%B6"><span class="toc-number">12.</span> <span class="toc-text"> 30. 垃圾回收机制</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#31promise%E7%9A%84%E7%90%86%E8%A7%A3"><span class="toc-number">13.</span> <span class="toc-text"> 31.Promise 的理解</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#32promise%E6%96%B9%E6%B3%95"><span class="toc-number">14.</span> <span class="toc-text"> 32.Promise 方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#33%E5%AF%B9asyncawait%E7%9A%84%E7%90%86%E8%A7%A3"><span class="toc-number">15.</span> <span class="toc-text"> 33. 对 async&#x2F;await 的理解</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#34-asyncawait%E5%AF%B9%E6%AF%94promise%E7%9A%84%E4%BC%98%E5%8A%BF"><span class="toc-number">16.</span> <span class="toc-text"> 34. async&#x2F;await 对比 Promise 的优势</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%B7%B1%E6%8B%B7%E8%B4%9D%E5%92%8C%E6%B5%85%E6%8B%B7%E8%B4%9D"><span class="toc-number">17.</span> <span class="toc-text"> 深拷贝和浅拷贝</span></a></li></ol>
      </div>
      <div class="related panel pjax" data-title="系列文章">
        <ul>
          <li><a href="/blog/2022/08/20/%E4%B9%9D.Vue/" rel="bookmark" title="vue总结">vue总结</a></li><li><a href="/blog/2023/04/18/%E5%8D%81.HTTP/" rel="bookmark" title="HTTP总结">HTTP总结</a></li><li><a href="/blog/2023/04/18/%E4%B8%80.%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%9F%BA%E7%A1%80%E6%80%BB%E7%BB%93/" rel="bookmark" title="计算机网络基础总结">计算机网络基础总结</a></li><li><a href="/blog/2023/04/21/%E4%BA%8C.Event%20Loop/" rel="bookmark" title="Event Loop">Event Loop</a></li><li><a href="/blog/2023/05/05/%E4%B8%89.Css/" rel="bookmark" title="CSS">CSS</a></li><li class="active"><a href="/blog/2023/05/17/%E5%9B%9B.JS/" rel="bookmark" title="JS">JS</a></li><li><a href="/blog/2023/06/12/%E4%BA%94.template/" rel="bookmark" title="Template">Template</a></li><li><a href="/blog/2023/07/03/%C2%A0%E5%85%AD.%E8%AF%BB%E6%BA%90%E7%A0%81%E7%90%86%E8%A7%A3Vnode/" rel="bookmark" title="读源码理解Vnode">读源码理解Vnode</a></li><li><a href="/blog/2023/07/18/%E4%B8%83.React/" rel="bookmark" title="React">React</a></li><li><a href="/blog/2023/07/20/%E5%85%AB.%E8%AF%BB%E3%80%8AVuejs%E8%AE%BE%E8%AE%A1%E4%B8%8E%E5%AE%9E%E7%8E%B0%E3%80%8B%E6%80%BB%E7%BB%93/" rel="bookmark" title="读《Vuejs设计与实现》总结">读《Vuejs设计与实现》总结</a></li><li><a href="/blog/2023/07/25/%E4%B9%9D.React%E9%9D%A2%E8%AF%95/" rel="bookmark" title="React面试">React面试</a></li><li><a href="/blog/2023/07/25/%E5%8D%81%E4%B8%80.%E8%87%AA%E6%B5%8B1/" rel="bookmark" title="自测1">自测1</a></li><li><a href="/blog/2023/08/15/%E5%8D%81%E4%BA%8C.Supense%E5%92%8C%E5%BC%82%E6%AD%A5%E7%BB%84%E4%BB%B6%E8%A7%A3%E5%86%B3%E9%A6%96%E9%A1%B5%E7%99%BD%E5%B1%8F%E9%97%AE%E9%A2%98/" rel="bookmark" title="Supense和异步组件解决首页白屏问题">Supense和异步组件解决首页白屏问题</a></li>
        </ul>
      </div>
      <div class="overview panel" data-title="站点概览">
        <div class="author" itemprop="author" itemscope itemtype="http://schema.org/Person">
  <img class="image" itemprop="image" alt="宋胖子"
      data-src="/blog/images/avatar.jpg">
  <p class="name" itemprop="name">宋胖子</p>
  <div class="description" itemprop="description">欢迎大家一起交流</div>
</div>

<nav class="state">
    <div class="item posts">
      <a href="/blog/archives/">
        <span class="count">13</span>
        <span class="name">文章</span>
      </a>
    </div>
    <div class="item categories">
      <a href="/blog/categories/">
        <span class="count">1</span>
        <span class="name">分类</span>
      </a>
    </div>
    <div class="item tags">
      <a href="/blog/tags/">
        <span class="count">1</span>
        <span class="name">标签</span>
      </a>
    </div>
</nav>

<div class="social">
</div>

<ul class="menu">
  
    
  <li class="item">
    <a href="/blog/" rel="section"><i class="ic i-home"></i>首页</a>
  </li>


</ul>

      </div>
    </div>
  </div>

  <ul id="quick">
    <li class="prev pjax">
        <a href="/blog/2023/05/05/%E4%B8%89.Css/" rel="prev" title="上一篇"><i class="ic i-chevron-left"></i></a>
    </li>
    <li class="up"><i class="ic i-arrow-up"></i></li>
    <li class="down"><i class="ic i-arrow-down"></i></li>
    <li class="next pjax">
        <a href="/blog/2023/06/12/%E4%BA%94.template/" rel="next" title="下一篇"><i class="ic i-chevron-right"></i></a>
    </li>
    <li class="percent"></li>
  </ul>
</div>


        </div>
        <div class="dimmer"></div>
      </div>
    </main>
    <footer id="footer">
      <div class="inner">
        <div class="widgets">
          
<div class="rpost pjax">
  <h2>随机文章</h2>
  <ul>
      
  <li class="item">
    
<div class="breadcrumb">
<a href="/blog/categories/%E6%88%91%E7%9A%84%E6%97%A5%E5%BF%97/" title="分类于 我的日志">我的日志</a>
</div>

    <span><a href="/blog/2023/05/05/%E4%B8%89.Css/" title="CSS">CSS</a></span>
  </li>

      
  <li class="item">
    
<div class="breadcrumb">
<a href="/blog/categories/%E6%88%91%E7%9A%84%E6%97%A5%E5%BF%97/" title="分类于 我的日志">我的日志</a>
</div>

    <span><a href="/blog/2023/06/12/%E4%BA%94.template/" title="Template">Template</a></span>
  </li>

      
  <li class="item">
    
<div class="breadcrumb">
<a href="/blog/categories/%E6%88%91%E7%9A%84%E6%97%A5%E5%BF%97/" title="分类于 我的日志">我的日志</a>
</div>

    <span><a href="/blog/2022/08/20/%E4%B9%9D.Vue/" title="vue总结">vue总结</a></span>
  </li>

      
  <li class="item">
    
<div class="breadcrumb">
<a href="/blog/categories/%E6%88%91%E7%9A%84%E6%97%A5%E5%BF%97/" title="分类于 我的日志">我的日志</a>
</div>

    <span><a href="/blog/2023/04/18/%E5%8D%81.HTTP/" title="HTTP总结">HTTP总结</a></span>
  </li>

      
  <li class="item">
    
<div class="breadcrumb">
<a href="/blog/categories/%E6%88%91%E7%9A%84%E6%97%A5%E5%BF%97/" title="分类于 我的日志">我的日志</a>
</div>

    <span><a href="/blog/2023/07/03/%C2%A0%E5%85%AD.%E8%AF%BB%E6%BA%90%E7%A0%81%E7%90%86%E8%A7%A3Vnode/" title="读源码理解Vnode">读源码理解Vnode</a></span>
  </li>

      
  <li class="item">
    
<div class="breadcrumb">
<a href="/blog/categories/%E6%88%91%E7%9A%84%E6%97%A5%E5%BF%97/" title="分类于 我的日志">我的日志</a>
</div>

    <span><a href="/blog/2023/07/25/%E4%B9%9D.React%E9%9D%A2%E8%AF%95/" title="React面试">React面试</a></span>
  </li>

      
  <li class="item">
    
<div class="breadcrumb">
<a href="/blog/categories/%E6%88%91%E7%9A%84%E6%97%A5%E5%BF%97/" title="分类于 我的日志">我的日志</a>
</div>

    <span><a href="/blog/2023/08/15/%E5%8D%81%E4%BA%8C.Supense%E5%92%8C%E5%BC%82%E6%AD%A5%E7%BB%84%E4%BB%B6%E8%A7%A3%E5%86%B3%E9%A6%96%E9%A1%B5%E7%99%BD%E5%B1%8F%E9%97%AE%E9%A2%98/" title="Supense和异步组件解决首页白屏问题">Supense和异步组件解决首页白屏问题</a></span>
  </li>

      
  <li class="item">
    
<div class="breadcrumb">
<a href="/blog/categories/%E6%88%91%E7%9A%84%E6%97%A5%E5%BF%97/" title="分类于 我的日志">我的日志</a>
</div>

    <span><a href="/blog/2023/07/18/%E4%B8%83.React/" title="React">React</a></span>
  </li>

      
  <li class="item">
    
<div class="breadcrumb">
<a href="/blog/categories/%E6%88%91%E7%9A%84%E6%97%A5%E5%BF%97/" title="分类于 我的日志">我的日志</a>
</div>

    <span><a href="/blog/2023/07/20/%E5%85%AB.%E8%AF%BB%E3%80%8AVuejs%E8%AE%BE%E8%AE%A1%E4%B8%8E%E5%AE%9E%E7%8E%B0%E3%80%8B%E6%80%BB%E7%BB%93/" title="读《Vuejs设计与实现》总结">读《Vuejs设计与实现》总结</a></span>
  </li>

      
  <li class="item">
    
<div class="breadcrumb">
<a href="/blog/categories/%E6%88%91%E7%9A%84%E6%97%A5%E5%BF%97/" title="分类于 我的日志">我的日志</a>
</div>

    <span><a href="/blog/2023/04/18/%E4%B8%80.%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%9F%BA%E7%A1%80%E6%80%BB%E7%BB%93/" title="计算机网络基础总结">计算机网络基础总结</a></span>
  </li>

  </ul>
</div>
<div>
  <h2>最新评论</h2>
  <ul class="leancloud-recent-comment"></ul>
</div>

        </div>
        <div class="status">
  <div class="copyright">
    
    &copy; 2010 – 
    <span itemprop="copyrightYear">2023</span>
    <span class="with-love">
      <i class="ic i-sakura rotate"></i>
    </span>
    <span class="author" itemprop="copyrightHolder">宋胖子 @ Yume Shoka</span>
  </div>
  <div class="powered-by">
    基于 <span class="exturl" data-url="aHR0cHM6Ly9oZXhvLmlv">Hexo</span> & Theme.<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL2FtZWhpbWUvaGV4by10aGVtZS1zaG9rYQ==">Shoka</span>
  </div>
</div>

      </div>
    </footer>
  </div>
<script data-config type="text/javascript">
  var LOCAL = {
    path: '2023/05/17/四.JS/',
    favicon: {
      show: "（●´3｀●）やれやれだぜ",
      hide: "(´Д｀)大変だ！"
    },
    search : {
      placeholder: "文章搜索",
      empty: "关于 「 ${query} 」，什么也没搜到",
      stats: "${time} ms 内找到 ${hits} 条结果"
    },
    valine: true,fancybox: true,
    copyright: '复制成功，转载请遵守 <i class="ic i-creative-commons"></i>BY-NC-SA 协议。',
    ignores : [
      function(uri) {
        return uri.includes('#');
      },
      function(uri) {
        return new RegExp(LOCAL.path+"$").test(uri);
      }
    ]
  };
</script>

<script src="https://cdn.polyfill.io/v2/polyfill.js"></script>

<script src="//cdn.jsdelivr.net/combine/npm/pace-js@1.0.2/pace.min.js,npm/pjax@0.2.8/pjax.min.js,npm/whatwg-fetch@3.4.0/dist/fetch.umd.min.js,npm/animejs@3.2.0/lib/anime.min.js,npm/algoliasearch@4/dist/algoliasearch-lite.umd.js,npm/instantsearch.js@4/dist/instantsearch.production.min.js,npm/lozad@1/dist/lozad.min.js,npm/quicklink@2/dist/quicklink.umd.js"></script>

<script src="/blog/js/app.js?v=0.2.5"></script>




</body>
</html>
